package com.zhkj.tools;

import com.sun.jna.platform.win32.Advapi32Util;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    private static String TITLE = "卷王提醒您~";
    private static String OVERTIME_START = "18:00";
    private static long OVERTIME_NEED = 30;

    public static void main(String[] args) {
        initConf();
        List<Event> evtList = getEvtList();
        evtList.forEach(System.out::println);

        long overDays = evtList.stream().filter(s -> s.getOverTimeMin() > 0).count();
        long sumMin = evtList.stream().mapToLong(Event::getOverTimeMin).sum();
        long leftMin = OVERTIME_NEED * 60 - sumMin;


        String log = String.format("本月已加班%s天，共%s，还剩%s，一给我哩giaogiao~", overDays, calculate(sumMin), calculate(leftMin));
        alert(log);
    }

    private static void initConf() {
        try {
            String path = JarTool.getJarDir().split("file:")[0] + File.separator + "卷王.ini";
            File file = new File(path);
            if(file.exists()){
                String s = FileUtils.readFileToString(file);
                for (String s1 : s.split("\n")) {
                    String[] kv = s1.split(StringPool.EQUALS);
                    switch (kv[0]){
                        case "标题":
                            TITLE = kv[1];
                            break;
                        case "开始加班时间":
                            OVERTIME_START = kv[1];
                            break;
                        case "本月需要加班时间":
                            OVERTIME_NEED = Long.parseLong(kv[1]);
                            break;
                    }
                }
            }else {
                System.out.println("创建配置文件：" + file.getPath());
                file.createNewFile();
                String config = String.format("标题=%s\n开始加班时间=%s\n本月需要加班时间=%s", TITLE, OVERTIME_START, OVERTIME_NEED);
                FileUtils.write(file, config, false);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private static String calculate(long min) {
        long sec = min * 60;
        String ret;
        if(sec < 60){
            ret = sec + "秒";
        }else if(sec < 3600){
            ret = String.format("%s分", sec / 60);
        }else {
            ret = String.format("%s小时%s分", sec / 3600, (sec % 3600 / 60));
        }
        return ret;
    }

    private static List<Event> getEvtList() {
        List<Event> eventList = new ArrayList<>();
        Advapi32Util.EventLogIterator iter = new Advapi32Util.EventLogIterator("EventLog");
        while (iter.hasNext()) {
            Advapi32Util.EventLogRecord record = iter.next();
            //get event generated time
            if ((short) record.getEventId() == 6006) {
                Date date = new Date(record.getRecord().TimeGenerated.longValue() * 1000);
                if((date.getMonth() + 1) == LocalDate.now().getMonthValue()) {
                    eventList.add(new Event(date));
                }
            }
        }
        // 同一天只保留最晚的一次记录
        Date now = new Date();
        List<Event> list = new ArrayList();
        eventList.stream().collect(Collectors.groupingBy(Event::getDay)).forEach((k, v) -> {
            list.add(v.stream().max(Comparator.comparingLong(Event::getTimestamp)).get());
        });
        // 过滤掉当天的关机记录，添加当前的时间
        List<Event> list1 = list.stream().filter(e -> e.getDay() < now.getDate())
                .collect(Collectors.toList());
        list1.add(new Event(now));
        return list1;
    }

    public static void alert(String content){
        try {
            String cmd = String.format("mshta vbscript:msgbox(\"%s\",64,\"%s\")(window.close)", content, TITLE);
//            String cmd = "msg %username% " + content;
//            String cmd = String.format("mshta \"javascript:new ActiveXObject('WScript.Shell').popup('%s',7,'%s',64);window.close();", content, TITLE);
            Runtime.getRuntime().exec(cmd);
        }catch (Exception e){ e.printStackTrace(); }
    }

    public static class Event implements Comparable<Event> {
        private final Date time;
        private final long overTimeMin;
        private final int day;
        private final long timestamp;
        private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        public Date getTime() {
            return time;
        }

        public long getOverTimeMin() {
            return overTimeMin;
        }

        public int getDay() {
            return day;
        }

        public long getTimestamp() {
            return timestamp;
        }

        @Override
        public int compareTo(Event o) {
            return o.getTime().compareTo(this.getTime());
        }

        public Event(Date time) {
            this.time = time;
            this.overTimeMin = calculateOverTime(time);
            this.day = time.getDate();
            this.timestamp = time.getTime();
        }

        private long calculateOverTime(Date time) {
            Date overTimeStart = new Date(time.getTime());
            String[] split = OVERTIME_START.split(StringPool.COLON);

            overTimeStart.setHours(Integer.parseInt(split[0]));
            overTimeStart.setMinutes(Integer.parseInt(split[1]));

            return Math.max(0, (time.getTime() - overTimeStart.getTime()) / 1000 / 60);
        }

        @Override
        public String toString() {
            final StringBuffer sb = new StringBuffer("Event{");
            sb.append("time=").append(simpleDateFormat.format(time));
            sb.append(", overTimeMin=").append(overTimeMin);
            sb.append('}');
            return sb.toString();
        }
    }
}